﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Threading;
using System.Runtime.InteropServices;

namespace tuoguan
{
    class Program
    {
        static void Main(string[] args)
        {
        }
    }
    public class BaseResource : IDisposable
    {
        // 非托管资源
        private IntPtr handle;
        //托管资源
        private Component Components;
        // Dispose是否被调用
        private bool disposed = false;

        public BaseResource()
        {
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }

        protected virtual void Dispose(bool disposing)
        {

            if (!this.disposed)
            {
                if (disposing)
                {
                    // 释放托管资源
                    Components.Dispose();
                }
                // 释放非托管资源，如果disposing为false, 
                // 只有托管资源被释放
                CloseHandle(handle);
                handle = IntPtr.Zero;
                // 注意这里不是线程安全的
            }
            disposed = true;
        }

        // 析构函数只会在我们没有直接调用Dispose方法的时候调用
        // 派生类中不用在次提供析构函数
        ~BaseResource()
        {
            Dispose(false);
        }

        // 如果你已经调用了Dispose方法后在调用其他方法会抛出ObjectDisposedException
        public void DoSomething()
        {
            if (this.disposed)
            {
                throw new ObjectDisposedException();
            }
        }
    }


    public class MyResourceWrapper : BaseResource
    {
        // 托管资源
        private Component addedManaged;
        // 非托管资源
        private IntPtr addedNative;
        private bool disposed = false;

        public MyResourceWrapper()
        {
        }

        protected override void Dispose(bool disposing)
        {
            if (!this.disposed)
            {
                try
                {
                    if (disposing)
                    {
                        addedManaged.Dispose();
                    }

                    CloseHandle(addedNative);
                    this.disposed = true;
                }
                finally
                {
                    base.Dispose(disposing);
                }
            }
        }
    }
}
